package com.hiwan.system.util;


import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

import com.hiwan.platform.utils.SpringContextHolder;
import com.hiwan.system.common.security.session.SessionDAO;
import com.hiwan.system.dao.menu.MenuDao;
import com.hiwan.system.dao.role.RoleDao;
import com.hiwan.system.dao.user.UserDao;
import com.hiwan.system.pojo.MenuInfo;
import com.hiwan.system.pojo.RoleInfo;
import com.hiwan.system.pojo.UserInfo;
import com.hiwan.system.security.realm.SystemAuthorizingRealm;
import com.hiwan.system.security.realm.SystemAuthorizingRealm.Principal;

/**
 * 
 * Datetime   ： 2016年1月5日 下午1:50:52<br>
 * Title      :  UserUtils.java<br>
 * Description:   用户工具类<br>
 * Company    :  hiwan<br>
 * @author cbj
 *
 */
public class UserCacheUtils {

	private static UserDao userDao = SpringContextHolder.getBean(UserDao.class);
	private static MenuDao menuDao = SpringContextHolder.getBean(MenuDao.class);
	private static RoleDao roleDao = SpringContextHolder.getBean(RoleDao.class);
	private static SystemAuthorizingRealm realm = SpringContextHolder.getBean("systemAuthorizingRealm");
	
	//第三方管理的缓存
	public static final String USER_CACHE = "userCache";
	public static final String USER_CACHE_ID_ = "id_";
	public static final String USER_CACHE_USER_NAME_ = "un_";
	
	//缓存在session中的数据
	public static final String CACHE_ROLE_LIST = "roleList";
	public static final String CACHE_ENABLE_ROLE_LIST = "enableRoleList";
	public static final String CACHE_MENU_LIST = "menuList";
	
	private static SessionDAO sessionDao = SpringContextHolder.getBean("sessionDAO");
	
	/**
	 * 根据ID获取用户
	 * @param id
	 * @return 取不到返回null
	 */
	public static UserInfo get(String id){
		UserInfo user = (UserInfo)CacheUtils.get(USER_CACHE, USER_CACHE_ID_ + id);
		if (user ==  null){
			UserInfo u=new UserInfo(id);
			user = userDao.selectOne(u);
			if (user == null){
				return null;
			}
			CacheUtils.put(USER_CACHE, USER_CACHE_ID_ + user.getUserId(), user);
			CacheUtils.put(USER_CACHE, USER_CACHE_USER_NAME_ + user.getUserName(), user);
		}
		return user;
	}
	
	/**
	 * 获取当前用户的所属机构
	 * @return
	 */
	public static String getOrgId(){
		return getUser().getOrgId();
	}
	
	/**
	 * 获取当前用户的Id
	 * @return
	 */
	public static String getId(){
		return getUser().getUserId();
	}
	/**
	 * 获取当前用户的所属部门
	 * @return
	 */
	public static String getDeptId(){
		return getUser().getDeptId();
	}
	/**
	 * 清除当前用户缓存
	 */
	public static void clearCache(){
		removeCache(CACHE_ROLE_LIST);
		removeCache(CACHE_MENU_LIST);
		removeAllCache(CACHE_ENABLE_ROLE_LIST);
		UserCacheUtils.clearCache(getUser());
	}
	
	
	/**
	 * 清除所有用户缓存
	 */
	public static void clearAllUserCache(){
		removeAllCache(CACHE_ROLE_LIST);
		removeAllCache(CACHE_MENU_LIST);
		removeAllCache(CACHE_ENABLE_ROLE_LIST);
		CacheUtils.removeCache(USER_CACHE);
		realm.clearAllCachedAuthorizationInfo();
	}
	
	
	/**
	 * 清除指定用户缓存
	 * @param user
	 */
	public static void clearCache(UserInfo user){
		CacheUtils.remove(USER_CACHE, USER_CACHE_ID_ + user.getUserId());
		CacheUtils.remove(USER_CACHE, USER_CACHE_USER_NAME_ + user.getUserName());
		realm.clearCachedAuthorizationInfo(new SystemAuthorizingRealm.Principal(user, false));
	}
	
	/**
	 * 获取当前登录者对象
	 * @return 取不到返回 new User()
	 */
	public static UserInfo getUser(){
		Principal principal = getPrincipal();
		if (principal!=null){
			UserInfo user = get(principal.getId());
			if (user != null){
				return user;
			}
			return new UserInfo();
		}
		// 如果没有登录，则返回实例化空的User对象。
		return new UserInfo();
	}

	/**
	 * 获取当前用户角色列表
	 * @return
	 */
	public static List<RoleInfo> getRoleList(){
//		@SuppressWarnings("unchecked")
		//List<RoleInfo> roleList = (List<RoleInfo>)getCache(CACHE_ROLE_LIST);
		clearCache();
		List<RoleInfo> roleList=new ArrayList<RoleInfo>();
//		if (roleList == null){
			UserInfo user = getUser();
			//TODO 01是网点外拓管理员，属于硬编码
//			if(getSubject().hasRole("01")){
//				roleList = roleDao.selectList(new RoleInfo());
//			}else{
				roleList = user.getRoles();
//			}
//			putCache(CACHE_ROLE_LIST, roleList);
//		}
			//排序
			RoleInfo r=roleDao.selectOne(user.getDefaultRole());
			for (int i = 0; i < roleList.size(); i++) {
				if(roleList.get(i).getRoleId().equals(user.getDefaultRole())){
					roleList.remove(i);
				}
			}
			roleList.add(0, r);
		return roleList;
	}
	/**
	 * 获取所有可用角色列表
	 * 列出hw_role表中所有可用的角色
	 * @return
	 */
	public static List<RoleInfo> getEnableRoleList(){
		@SuppressWarnings("unchecked")
		List<RoleInfo> roleList = (List<RoleInfo>)getCache(CACHE_ENABLE_ROLE_LIST);
		if (roleList == null){
			RoleInfo ri=new RoleInfo();
			ri.setRoleStatus("1");
			roleList = roleDao.selectList(ri);
			putCache(CACHE_ENABLE_ROLE_LIST, roleList);
		}
		return roleList;
	}
	
	/**
	 * 获取当前用户授权菜单
	 * @return
	 */
	public static List<MenuInfo> getMenuList(){
//		@SuppressWarnings("unchecked")
//		List<MenuInfo> menuList = (List<MenuInfo>)getCache(CACHE_MENU_LIST);
//		if (menuList == null || menuList.isEmpty()){
		UserInfo user = getUser();
			/*if (user.isAdmin()){
				menuList = menuDao.selectMenuList("");
			}else{*/
		
		List<MenuInfo> menuList = menuDao.selectUserMenusByRoleId(user);
			//}
//			putCache(CACHE_MENU_LIST, menuList);
//		}
		return menuList;
	}
	
	/**
	 * 获取授权主要对象
	 */
	public static Subject getSubject(){
		return SecurityUtils.getSubject();
	}
	
	/**
	 * 获取当前登录者对象
	 */
	public static Principal getPrincipal(){
		try{
			Subject subject = SecurityUtils.getSubject();
			Principal principal = (Principal)subject.getPrincipal();
			if (principal != null){
				return principal;
			}
		}catch (UnavailableSecurityManagerException e) {
			
		}catch (InvalidSessionException e){
			
		}
		return null;
	}
	
	public static Session getSession(){
		try{
			Subject subject = SecurityUtils.getSubject();
			Session session = subject.getSession(false);
			if (session == null){
				session = subject.getSession();
			}
			if (session != null){
				return session;
			}
		}catch (InvalidSessionException e){
			
		}
		return null;
	}
	
	// ============== User Cache ==============
	
	public static Object getCache(String key) {
		return getCache(key, null);
	}
	
	public static Object getCache(String key, Object defaultValue) {
		Object obj = getSession().getAttribute(key);
		return obj==null?defaultValue:obj;
	}

	public static void putCache(String key, Object value) {
		getSession().setAttribute(key, value);
	}

	public static void removeCache(String key) {
		getSession().removeAttribute(key);
	}
	
	public static void removeAllCache(String key) {
		Collection<Session> activeSessions = sessionDao.getActiveSessions();
		for (Session session : activeSessions) {
			session.removeAttribute(key);
		}
	}
	
}
